Skip to content

fix: refresh stale squad.agent.md greeting version on re-init - #1995

Draft
tamirdresher wants to merge 1 commit into
bradygaster:devfrom
tamirdresher:fix/reinit-stale-version-greeting
Draft

fix: refresh stale squad.agent.md greeting version on re-init#1995
tamirdresher wants to merge 1 commit into
bradygaster:devfrom
tamirdresher:fix/reinit-stale-version-greeting

Conversation

@tamirdresher

Copy link
Copy Markdown
Collaborator

What

Fixes squad.agent.md's first-response greeting literal (backtick-quoted `Squad v...`) staying stamped with a stale version when squad init is re-run against an already-initialized project, even though the HTML comment marker (<!-- version: ... -->) and the Identity - **Version:** line are correctly refreshed on the same re-run.

Why

squad init always calls stampVersion() on an existing squad.agent.md after sdkInitSquad() returns, regardless of skipExisting, to "ensure the version is fully stamped". stampVersion (in packages/squad-cli/src/cli/core/version.ts) and its SDK counterpart stampVersionInContent (in packages/squad-sdk/src/config/init.ts, used when generating a fresh squad.agent.md from the template) each replace three version locations. The first two regexes (<!-- version: ... --> and - **Version:** ...) are written permissively and are idempotent — they match any prior value, resolved or not. The third regex, however, only matched the unresolved `Squad v{version}` placeholder token. Once a real version had been stamped once, the placeholder text no longer existed in the file, so every subsequent re-stamp silently left the greeting literal on whatever version it was last set to.

Not affected: squad upgrade fully rewrites squad.agent.md from the template (which always contains the unresolved placeholder) before stamping, so the placeholder is always present there — the regression is specific to the re-init / skipExisting=true path.

How

Widened the third regex in both stampVersion and stampVersionInContent from matching only `Squad v\{version\}` to matching `Squad v[^`]*` — i.e. anything between `Squad v and the closing backtick. This still matches the unresolved placeholder, and now also matches an already-resolved semver (with or without a prerelease suffix), making the replacement idempotent regardless of the file's current state. Both implementations were kept in sync per existing convention (each package has its own copy of the stamping logic).

Added regression coverage in test/cli/init.test.ts:

  • A direct unit test that seeds a stale resolved `Squad v0.9.0` literal (plus stale marker/Version line) and asserts stampVersion() refreshes all three locations.
  • A full re-init integration test: runInit() once, mutate the resulting squad.agent.md to simulate an older installed version in all three locations (not the {version} placeholder), runInit() again against the same project (hits the skipExisting=true / existing-file path), and assert every version location — including the greeting literal — now matches the current version.

PR Readiness Checklist

Branch & Commit

  • Branch created from dev (upstream/dev, not main)
  • Branch is up to date with dev
  • PR is in draft mode (by request)
  • Commit history is clean (single commit)

Build & Test

  • npm run build -w packages/squad-cli passes
  • npm run build -w packages/squad-sdkfails on upstream/dev baseline, unrelated to this change (see Waivers)
  • Targeted tests pass: npx vitest run test/cli/init.test.ts (18/18, including 2 new regression tests)
  • Adjacent suite passes: test/cli/upgrade.test.ts, test/cli/init-upgrade-parity.test.ts, test/init-sdk.test.ts, test/init.test.ts, test/init-scaffolding.test.ts (all pass in isolation; see Waivers for a flaky test under full-suite parallel load)
  • npm test (full suite) — not run to completion; see Waivers
  • npm run lintfails on upstream/dev baseline, unrelated to this change (see Waivers)
  • npm run lint:eslint on changed files — 0 errors (63 pre-existing n/no-sync warnings in init.ts, untouched by this diff)

Changeset

  • Changeset added via manual .changeset/fix-reinit-stale-version-greeting.md (patch, both @bradygaster/squad-cli and @bradygaster/squad-sdk)

Docs

  • N/A — no user-facing/docs change, internal stamping-logic bugfix

Exports

  • N/A — no new modules, no public API change

Breaking Changes

None.

Waivers

  • Waived: npm run build (squad-sdk) / npm run lint — both fail identically on a clean upstream/dev checkout (verified by stashing this PR's changes and re-running) with 6 pre-existing TypeScript errors in packages/squad-sdk/src/adapter/client.ts (RuntimeConnection not exported by @github/copilot-sdk, CopilotClientOptions.connection, ModelBilling.tokenPrices, CopilotClient.onLifecycle, etc.). This file is untouched by this PR. Requesting a maintainer confirm this is known baseline debt (skip-changelog/reviewer waiver as appropriate — not requesting skip-changelog since a changeset is included).
  • Waived: full npm test run — running the complete suite locally (npx vitest run, ~6400 tests, no path filter) produced widespread, unrelated failures across dozens of test files with no relation to this diff (e.g. test/storage-provider.test.ts, test/session-adapter.test.ts, test/scripts/check-shebang-eol.test.ts), consistent with local resource contention under full parallelism rather than a real regression. Also observed: at least one test in this run (apparently a self-upgrade/dogfooding test) wrote to this checkout's own .squad/config.json and .github/agents/squad.agent.md; both were reverted before committing and are not part of this PR's diff. Given the risk of further side effects against this real checkout, I did not force a full run to completion. All targeted and directly-adjacent suites (see above) pass. Requesting CI be the source of truth for the full-suite gate on this PR.
  • Waived: test/init-scaffolding.test.ts intermittent failure under combined loadno-remote resilience (#579) > initSquad/runInit succeeds in a git repo with no remote and a doctor sub-test flip between pass/fail depending on what else is running concurrently; the full file passes 26/26 in isolation on two separate runs. Not caused by this change (no code in this diff is exercised by that test).

Do not link/close #1589 — related area but a different bug.

Re-running squad init against an already-initialized project could leave
the squad.agent.md first-response greeting (backtick-quoted ` Squad
v... `) stamped with an old version even though the HTML comment marker
and Identity Version: line were correctly refreshed.

Root cause: stampVersion (squad-cli) and stampVersionInContent
(squad-sdk) each replace three version locations, but the third regex only
matched the unresolved ` Squad v{version} ` placeholder. Once a real
version had been stamped once, the placeholder was gone, so later
re-stamps could no longer touch the greeting literal.

Fix: broaden the greeting regex in both functions to also match an
already-resolved ` Squad vX.Y.Z ` literal, so all three locations stay
idempotently in sync on every re-init or upgrade.

Adds regression coverage in test/cli/init.test.ts: a direct stampVersion
unit test, and a full re-init integration test that seeds a stale resolved
version in all three locations and asserts init.ts's existing-file
re-stamp brings them back in sync.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b73147c1-252d-473c-be2b-df22d9faf163
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🟡 Impact Analysis — PR #1995

Risk tier: 🟡 MEDIUM

📊 Summary

Metric Count
Files changed 4
Files added 1
Files modified 3
Files deleted 0
Modules touched 4

🎯 Risk Factors

  • 4 files changed (≤5 → LOW)
  • 4 modules touched (2-4 → MEDIUM)

📦 Modules Affected

root (1 file)
  • .changeset/fix-reinit-stale-version-greeting.md
squad-cli (1 file)
  • packages/squad-cli/src/cli/core/version.ts
squad-sdk (1 file)
  • packages/squad-sdk/src/config/init.ts
tests (1 file)
  • test/cli/init.test.ts

This report is generated automatically for every PR. See #733 for details.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🛫 PR Readiness Check

ℹ️ This comment updates on each push. Last checked: commit 5b1cdd2

PR Scope: 📦🔧 Mixed (product + infrastructure)

⚠️ 3 item(s) to address before review

Status Check Details
Single commit 1 commit — clean history
Not in draft PR is still in draft — mark as ready for review when done
Branch up to date Up to date with dev
Copilot review No Copilot review yet — it may still be processing
Changeset present Changeset file found
Scope clean No .squad/ or docs/proposals/ files
No merge conflicts No merge conflicts
Copilot threads resolved No Copilot review threads
CI passing 10 check(s) still running

Files Changed (4 files, +74 −6)

File +/−
.changeset/fix-reinit-stale-version-greeting.md +6 −0
packages/squad-cli/src/cli/core/version.ts +4 −2
packages/squad-sdk/src/config/init.ts +4 −2
test/cli/init.test.ts +60 −2

Total: +74 −6


This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🏗️ Architectural Review

⚠️ Architectural review: 1 warning(s).

Severity Category Finding Files
🟡 warning bootstrap-area 1 file(s) in the bootstrap area (packages/squad-cli/src/cli/core/) were modified. These files must maintain zero external dependencies. Review carefully. packages/squad-cli/src/cli/core/version.ts

Automated architectural review — informational only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(cli): squad upgrade silently overwrites and can downgrade .github/agents/squad.agent.md

1 participant